package cn.scw.common.utils;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

    //判断文件目录是否存在 如否则新建
    public static void checkFolder(File file) {
        System.out.println(file.exists());
        System.out.println(file.getName());
        if (!file.exists()) {//如果目录存在
            file.mkdirs();//创建目录
        }
    }

    //判断文件目录是否存在 如否则新建
    public static void chenkFile(File file) {
        if (!file.exists()) {//如果目录存在
            try {
                file.createNewFile();//创建目录
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 打包文件夹
     *
     * @param files    文件夹地址
     * @param response
     */
    public static void zip(List<File> files, String downloadName, HttpServletResponse response) {
        ZipOutputStream out = null;
        BufferedOutputStream bos = null;
        try {
            //将zip以流的形式输出到前台
            response.setHeader("content-type", "application/octet-stream");
            response.setCharacterEncoding("utf-8");
            // 设置浏览器响应头对应的Content-disposition
            //参数中 testZip 为压缩包文件名，尾部的.zip 为文件后缀
            response.setHeader("Content-disposition", "attachment;filename=" + new String(downloadName.getBytes("UTF-8"), "UTF-8") + ".zip");
            //创建zip输出流
            out = new ZipOutputStream(response.getOutputStream());
            //创建缓冲输出流
            bos = new BufferedOutputStream(out);
            //调用压缩函数
            for (File file : files) compress(out, file, file.getName());
            out.flush();
            bos.flush();
            System.out.println("压缩完成");
        } catch (Exception e) {
            System.out.println("ZIP压缩异常：" + e.getMessage());
        } finally {
            try {
                if (bos != null) bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (out != null) out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void zip(String sourceFile, String zipName) {
        ZipOutputStream out = null;
        BufferedOutputStream bos = null;
        try {
            File file = new File(sourceFile + "/" + zipName + ".zip");
            out = new ZipOutputStream(new FileOutputStream(file));
            //创建缓冲输出流
            bos = new BufferedOutputStream(out);
            compress(out, new File(sourceFile), "");
            out.flush();
            bos.flush();
            System.out.println("压缩完成");
        } catch (Exception e) {
            System.out.println("ZIP压缩异常：" + e.getMessage());
        } finally {
            try {
                if (bos != null) bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (out != null) out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void compress(ZipOutputStream out, File sourceFile, String base) {
        FileInputStream fos = null;
        BufferedInputStream bis = null;
        try {
            //如果路径为目录（文件夹）
            if (sourceFile.isDirectory()) {
                //取出文件夹中的文件（或子文件夹）
                File[] files = sourceFile.listFiles();
                if (files != null) {
                    if (files.length == 0) {//如果文件夹为空，则只需在目的地zip文件中写入一个目录进入点
                        out.putNextEntry(new ZipEntry(sourceFile.getName() + "/"));
                    } else {//如果文件夹不为空，则递归调用compress，文件夹中的每一个文件（或文件夹）进行压缩
                        for (int i = 0, len = files.length; i < len; i++) {
                            if (!files[i].getName().contains("imageCode")) compress(out, files[i], files[i].getName());
                        }
                    }
                }
            } else {//如果不是目录（文件夹），即为文件，则先写入目录进入点，之后将文件写入zip文件中
                out.putNextEntry(new ZipEntry(base));
                fos = new FileInputStream(sourceFile);
                bis = new BufferedInputStream(fos);
                int tag;
                //将源文件写入到zip文件中
                while ((tag = bis.read()) != -1) {
                    out.write(tag);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *  * 删除文件夹及其子文件（递归方式）
     *  
     **/
    public static boolean deleteDirectory(File dir) {
        if (dir.isDirectory()) {
            File[] subFiles = dir.listFiles();
            for (int i = 0; i < subFiles.length; i++) {
                boolean success = deleteDirectory(subFiles[i]);
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }

    @Data
    @EqualsAndHashCode(callSuper = false)
    public static class ZipModel implements Serializable {

        private static final long serialVersionUID = -5108446027952072973L;

        private String name;

        private String extension;

        private String url;
    }
}
